﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ttbit.form;
using static ttbit.form.FontData;

namespace ttbit.form
{

    public class PalData
    {
        public byte colorcount;
        public byte[] paldata;//r g b byte array;len =colorcount*3;

    }
    public class ImgData
    {
        const string magic = "TTIMG_V1";
        public TTIMGFormat format;
        public List<PalData> pals;
        public int width;
        public int height;
        public byte[] pixel;
        public void Write(System.IO.BinaryWriter stream)
        {
            byte[] buf = System.Text.Encoding.ASCII.GetBytes(magic.Substring(0, 8));
            if (buf.Length != 8)
                throw new Exception("error magic,must 8");
            stream.Write(buf, 0, 8);

            stream.Write((byte)format);

            bool needpal = (format == TTIMGFormat.PAL8 || format == TTIMGFormat.P5A3);
            if (needpal)
            {
                if (pals.Count > 255)
                    throw new Exception("too mush pals.");
                if (
                    (format == TTIMGFormat.PAL8 || format == TTIMGFormat.P5A3)
                    && pals.Count == 0)
                    throw new Exception("need pal but have noone.");

                stream.Write((byte)pals.Count);
                for (var i = 0; i < pals.Count; i++)
                {
                    stream.Write((byte)pals[i].colorcount);
                    if (format == TTIMGFormat.PAL8)
                        stream.Write(pals[i].paldata, 0, 256 * 4);
                    else if (format == TTIMGFormat.P5A3)
                        stream.Write(pals[i].paldata, 0, 32 * 4);
                    else
                        throw new Exception("shoud not be here.");
                }
            }
            else
            {
                stream.Write((byte)0);
            }
            if (width > 2048 || height > 2048)
                throw new Exception("size is too large.");
            stream.Write((ushort)width);
            stream.Write((ushort)height);
            int bytelen = format == TTIMGFormat.RGBA ? 4 : 1;
            stream.Write(pixel, 0, width * height * bytelen);
        }
        public void Read(System.IO.BinaryReader stream)
        {
            byte[] buf = stream.ReadBytes(8);// (buf, 0, 8);
            var tm = System.Text.Encoding.ASCII.GetString(buf, 0, 8);
            if (tm != magic.Substring(0, 8))
                throw new Exception("not ttimg file");

            this.format = (TTIMGFormat)stream.ReadByte();
            if (this.format > TTIMGFormat.RGBA)
                throw new Exception("error format");

            bool needpal = (format == TTIMGFormat.PAL8 || format == TTIMGFormat.P5A3);

            var palcount = stream.ReadByte();
            this.pals = new List<PalData>();
            if (!needpal && palcount > 0)
                throw new Exception("donot need pal but got >0.");
            if (needpal && palcount == 0)
                throw new Exception("need pal but got =0.");
            for (var i = 0; i < palcount; i++)
            {
                PalData pal = new PalData();
                pal.colorcount = stream.ReadByte();
                if (format == TTIMGFormat.PAL8)
                    pal.paldata = stream.ReadBytes(256 * 4);
                else if (format == TTIMGFormat.P5A3)
                    pal.paldata = stream.ReadBytes(32 * 4);
                else
                    throw new Exception("shoud not be here.");
                this.pals.Add(pal);
            }
            this.width = stream.ReadUInt16();
            this.height = stream.ReadUInt16();
            int bytelen = format == TTIMGFormat.RGBA ? 4 : 1;
            this.pixel = stream.ReadBytes(width * height * bytelen);
        }
    }


}
public enum TTIMGFormat
{
    P5A3,//32 color with palette + 8 alpha
    PAL8,//256 color with palette
    GRAY,//256 color (with a fix gray palette)
    RGBA,//最暴躁的保存方式，先存工具屏蔽
}
public class TTImg
{
    private TTImg()
    {

    }
    public string Name
    {
        get;
        private set;
    }
    public TTIMGFormat format;
    public int width;
    public int height;
    public byte[] pixel;
    public static TTImg FromAssetByName(string name)
    {
        var item = Env.RootPack.GetPackItem(name);
        if (item.Type == ".ttimg")
        {
            TTImg img = new TTImg();
            img.Name = item.Name;
            ImgData data = new ImgData();
            using var ms = new System.IO.MemoryStream(item.Bytes);
            using var br = new BinaryReader(ms);
            data.Read(br);
            img.format = data.format;
            img.pixel = data.pixel;
            img.width = data.width;
            img.height = data.height;
            return img;
        }
        else if (item.IsText == false)
        {
            BitmapData bitmap = new BitmapData();
            bitmap.LoadRGBA(item.Bytes);
            TTImg img = new TTImg();
            img.Name = item.Name;
            img.format = TTIMGFormat.RGBA;
            img.pixel = bitmap.data;
            img.width = bitmap.width;
            img.height = bitmap.height;
            return img;
        }
        else
        {
            return null;
        }
    }
    public static TTImg FromAsset(JSPackItem item)
    {
        if (item.Type == ".ttimg")
        {
            TTImg img = new TTImg();
            img.Name = item.Name;
            ImgData data = new ImgData();
            using var ms = new System.IO.MemoryStream(item._item.Bytes);
            using var br = new BinaryReader(ms);
            data.Read(br);
            img.format = data.format;
            img.pixel =  data.pixel;
            img.width = data.width;
            img.height = data.height;
            return img;
        }
        else if (item.IsText == false)
        {
            BitmapData bitmap = new BitmapData();
            bitmap.LoadRGBA(item._item.Bytes);
            TTImg img = new TTImg();
            img.Name = item.Name;
            img.format = TTIMGFormat.RGBA;
            img.pixel = bitmap.data;
            img.width = bitmap.width;
            img.height = bitmap.height;
            return img;
        }
        else
        {
            return null;
        }

    }

}